package br.com.sismo.client;

import java.util.ArrayList;
import java.util.List;

import br.com.sismo.shared.CursoTO;
import br.com.sismo.shared.TipoUsuario;
import br.com.sismo.shared.UsuarioTO;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class SisMO implements EntryPoint {

	private final GreetingServiceAsync greetingService = GWT
			.create(GreetingService.class);

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		generateMenu();
	}

	private void generateMenu() {
		final MenuBar superMenu = new MenuBar();
		final MenuBar usuarioBar = new MenuBar();
		final MenuBar cursoBar = new MenuBar();
		final MenuItem usuarioAdicionar = new MenuItem("Adicionar",
				new Command() {
					@Override
					public void execute() {
						clearBody();
						generateUsuarioForm();
					}
				});
		final MenuItem usuarioListar = new MenuItem("Listar", new Command() {
			@Override
			public void execute() {
				clearBody();
				generateUsuarioTable();
			}
		});
		final MenuItem cursoAdicionar = new MenuItem("Listar",
				new Command() {
					@Override
					public void execute() {
						clearBody();
						generateCursoTable();
						
					}
				});
		final MenuItem cursoListar = new MenuItem("Adicionar", new Command() {
			@Override
			public void execute() {
				clearBody();				
				generateCursoForm();
			}
		});
		superMenu.addItem("Usuário", usuarioBar);
		superMenu.addItem("Curso", cursoBar);
		usuarioBar.addItem(usuarioListar);
		usuarioBar.addItem(usuarioAdicionar);
		cursoBar.addItem(cursoAdicionar);
		cursoBar.addItem(cursoListar);		
		RootPanel.get("menu").add(superMenu);
	}

	private void generateCursoTable() {
		final List<CursoTO> cursos = new ArrayList<CursoTO>();
		greetingService.findAllCursos(new AsyncCallback<List<CursoTO>>() {
			@Override
			public void onFailure(Throwable caught) {
				RootPanel.get("message").add(
						new Label("Erro na busca de Cursos"));
			}

			@Override
			public void onSuccess(List<CursoTO> result) {
				if (result.size() <= 0) {
					clearBody();
					RootPanel.get("entityBody").add(new Label("Sem Cursos"));
					return;
				}
				cursos.addAll(result);
				final FlexTable table = new FlexTable();
				table.setText(0, 0, "Nome");
				table.setText(0, 1, "Descrição");
				table.setText(0, 2, "Alunos");
				table.setText(0, 3, "Remover");
				class RemoverBotao extends Button {
					private Long id;
					RemoverBotao(Long id, String label) {
						super(label);
						this.id = id;
						this.addClickHandler(new ClickHandler() {
							@Override
							public void onClick(ClickEvent event) {
								greetingService.removeCurso(getId(),
										new AsyncCallback<Void>() {
											@Override
											public void onFailure(
													Throwable caught) {
											}
											@Override
											public void onSuccess(Void result) {
												clearBody();
												generateCursoTable();
												RootPanel
														.get("message")
														.add(new Label(
																"Curso removido com sucesso"));
											}
										});
							}
						});
					}
					public Long getId() {
						return this.id;
					}
				};
				class DetalharBotao extends Button {
					private List<Long> alunosId;
					DetalharBotao(List<Long> alunos, String label) {
						super(label);
						this.alunosId = alunos;
						this.addClickHandler(new ClickHandler() {							
							@Override
							public void onClick(ClickEvent event) {
								greetingService.findUsuariosByIds(alunosId, new AsyncCallback<List<UsuarioTO>>() {
									@Override
									public void onFailure(Throwable caught) {										
									}
									@Override
									public void onSuccess(List<UsuarioTO> result) {
										if(result == null || result.size() == 0) {
											RootPanel.get("listaDeAlunosDoCurso").clear();
											RootPanel.get("listaDeAlunosDoCurso").add(new Label("Curso sem alunos"));
										}
										final FlexTable table = new FlexTable();
										table.setText(0, 0, "Nome");
										table.setText(0, 1, "E-mail");
										table.setText(0, 2, "Login");
										table.setText(0, 3, "Tipo de Usuário");
										int row = 1;
										for (UsuarioTO u : result) {
											table.setText(row, 0, u.getNome());
											table.setText(row, 1, u.getEmail());
											table.setText(row, 2, u.getLogin());
											table.setText(row, 3,
													TipoUsuario.porCodigo(u.getCodigoTipo())
															.getDescricao());
											row++;
										}
										RootPanel.get("listaDeAlunosDoCurso").clear();
										RootPanel.get("listaDeAlunosDoCurso").add(table);
									}
								});
							}
						});
					}
				};
				int row = 1;
				for (CursoTO u : cursos) {
					table.setText(row, 0, u.getNome());
					table.setText(row, 1, u.getDesc());
					table.setWidget(row, 2, new DetalharBotao(u.getAlunos(), "Detalhar"));
					table.setWidget(row, 3, new RemoverBotao(u.getId(),
							"X"));
					row++;
				}
				clearBody();
				RootPanel.get("entityBody").add(table);
			}
		});
	}

	private void generateCursoForm() {
		// Add
		final Grid grid = new Grid(3, 2);
		final Label nomeLabel = new Label("Nome");
		final TextBox nomeBox = new TextBox();
		nomeBox.setFocus(true);
		final Label descLabel = new Label("Descrição");
		final TextArea descBox = new TextArea();
		final Button enviar = new Button("Enviar");
		enviar.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				CursoTO c = new CursoTO();
				c.setNome(nomeBox.getValue());
				c.setDesc(descBox.getValue());
				c.setAlunos(new ArrayList<Long>());
				greetingService.addCurso(c, new AsyncCallback<Void>() {
					@Override
					public void onFailure(Throwable caught) {
					}

					@Override
					public void onSuccess(Void result) {
						clearBody();
						RootPanel.get("message").add(
								new Label("Curso Adicionado"));
					}
				});
			}
		});
		grid.setWidget(0, 0, nomeLabel);
		grid.setWidget(0, 1, nomeBox);
		grid.setWidget(1, 0, descLabel);
		grid.setWidget(1, 1, descBox);
		grid.setWidget(2, 1, enviar);
		RootPanel.get("entityBody").add(grid);
	}

	private void generateUsuarioTable() {
		final List<UsuarioTO> usuarios = new ArrayList<UsuarioTO>();
		greetingService.findAllUsuarios(new AsyncCallback<List<UsuarioTO>>() {
			@Override
			public void onFailure(Throwable caught) {
				RootPanel.get("message").add(
						new Label("Erro na busca de Usuarios"));
			}

			@Override
			public void onSuccess(List<UsuarioTO> result) {
				if (result.size() <= 0) {
					clearBody();
					RootPanel.get("entityBody").add(new Label("Sem usuários"));
					return;
				}
				usuarios.addAll(result);
				final FlexTable table = new FlexTable();
				table.setText(0, 0, "Nome");
				table.setText(0, 1, "E-mail");
				table.setText(0, 2, "Login");
				table.setText(0, 3, "Tipo de Usuário");
				table.setText(0, 4, "Remover");
				class RemoverBotao extends Button {
					private Long id;

					RemoverBotao(Long id, String label) {
						super(label);
						this.id = id;
						this.addClickHandler(new ClickHandler() {
							@Override
							public void onClick(ClickEvent event) {
								greetingService.removeUsuario(getId(),
										new AsyncCallback<Void>() {
											@Override
											public void onFailure(
													Throwable caught) {
											}

											@Override
											public void onSuccess(Void result) {
												clearBody();
												generateUsuarioTable();
												RootPanel
														.get("message")
														.add(new Label(
																"Usuário removido com sucesso"));
											}
										});
							}
						});
					}

					public Long getId() {
						return this.id;
					}
				}
				;
				int row = 1;
				for (UsuarioTO u : usuarios) {
					table.setText(row, 0, u.getNome());
					table.setText(row, 1, u.getEmail());
					table.setText(row, 2, u.getLogin());
					table.setText(row, 3,
							TipoUsuario.porCodigo(u.getCodigoTipo())
									.getDescricao());
					table.setWidget(row, 4, new RemoverBotao(u.getId(),
							"Remover"));
					row++;
				}
				clearBody();
				RootPanel.get("entityBody").add(table);
			}
		});
	}

	private void generateUsuarioForm() {
		// Add
		final Grid grid = new Grid(6, 2);
		final Label nomeLabel = new Label("Nome");
		final TextBox nomeBox = new TextBox();
		nomeBox.setFocus(true);
		final Label emailLabel = new Label("E-mail");
		final TextBox emailBox = new TextBox();
		final Label passwordLabel = new Label("Password");
		final PasswordTextBox passwordBox = new PasswordTextBox();
		final Label loginLabel = new Label("Login");
		final TextBox loginBox = new TextBox();
		final Label tipoLabel = new Label("Tipo");
		final ListBox tipoBox = new ListBox();
		for (TipoUsuario t : TipoUsuario.values()) {
			tipoBox.addItem(t.getDescricao());
		}
		final Button enviar = new Button("Enviar");
		enviar.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				UsuarioTO u = new UsuarioTO();
				u.setNome(nomeBox.getValue());
				u.setEmail(emailBox.getValue());
				u.setPassword(passwordBox.getValue());
				u.setLogin(loginBox.getValue());
				u.setCodigoTipo(tipoBox.getSelectedIndex() + 1);
				greetingService.addUsuario(u, new AsyncCallback<Void>() {
					@Override
					public void onFailure(Throwable caught) {
					}

					@Override
					public void onSuccess(Void result) {
						clearBody();
						RootPanel.get("message").add(
								new Label("Usuário Adicionado"));
					}
				});
			}
		});
		grid.setWidget(0, 0, nomeLabel);
		grid.setWidget(0, 1, nomeBox);
		grid.setWidget(1, 0, emailLabel);
		grid.setWidget(1, 1, emailBox);
		grid.setWidget(2, 0, passwordLabel);
		grid.setWidget(2, 1, passwordBox);
		grid.setWidget(3, 0, loginLabel);
		grid.setWidget(3, 1, loginBox);
		grid.setWidget(4, 0, tipoLabel);
		grid.setWidget(4, 1, tipoBox);
		grid.setWidget(5, 1, enviar);
		RootPanel.get("entityBody").add(grid);
	}

	private void clearBody() {
		RootPanel.get("message").clear();
		RootPanel.get("entityBody").clear();
		RootPanel.get("listaDeAlunosDoCurso").clear();
	}
}
